<template>
	<view class="booking-fixed">
		<!-- 导航栏 -->
		<nav-bar></nav-bar>
		<!-- 未选择提示 -->
		<view class="unselected-tips" v-if="showUnselectedTips && (!serviceInfo.id || !selectedDate || !selectedTime)">
			<view class="tips-item" v-if="!serviceInfo.id" @tap="scrollToService">
				<text class="icon">●</text>
				<text>选择服务项目</text>
				<text class="jump-text">点击跳转</text>
			</view>
			<view class="tips-item" v-if="!selectedDate || !selectedTime" @tap="scrollToTime">
				<text class="icon">●</text>
				<text>选择服务时间</text>
				<text class="jump-text">点击跳转</text>
			</view>
		</view>
		<!-- 地图区域 -->
		<view class="map-container">
			<map class="store-map" :latitude="mapInfo.latitude" :longitude="mapInfo.longitude" :markers="mapMarkers"
				:scale="16" show-location></map>
		</view>
		<!-- 门店信息 -->
		<view class="store-info">
			<view class="section-title">门店信息</view>
			<view class="store-card">
				<text class="name">{{ storeInfo.name }}</text>
				<text class="address">{{ storeInfo.address }}</text>
				<view class="contact-info">
					<text class="phone" @tap="makePhoneCall">{{ storeInfo.phone || '暂无电话' }}</text>
					<text class="distance" v-if="storeInfo.distance">距您{{ storeInfo.distance }}km</text>
				</view>
			</view>
		</view>
		<!-- 已选技师信息 -->
		<view class="selected-tech">
			<view class="section-title">服务技师</view>
			<view class="tech-card">
				<image class="avatar" :src="techInfo.avatar" mode="aspectFill"></image>
				<view class="info">
					<view class="name-row">
						<text class="name">{{ techInfo.name }}</text>
						<text class="title">{{ techInfo.title }}</text>
					</view>
					<view class="rating">
						<text class="score">{{ techInfo.score }}分</text>
						<text class="orders">已服务{{ techInfo.orders }}人</text>
					</view>
				</view>
			</view>
		</view>
		<!-- 服务项目选择 -->
		<view class="service-selection">
			<view class="section-title">
				<text>选择服务项目</text>
				<text class="scroll-tip">可滚动查看更多</text>
			</view>
			<scroll-view scroll-y="true" class="service-list">
				<view class="service-item" v-for="item in serviceList" :key="item.id"
					:class="{ active: serviceInfo.id === item.id }" @tap="selectService(item)">
					<image class="service-image" :src="item.img" mode="aspectFill"></image>
					<view class="service-content">
						<text class="name">{{ item.name }}</text>
						<text class="desc">{{ item.projectDesp || '暂无描述' }}</text>
						<view class="info">
							<view class="duration">
								<image class="duration-icon" src="/static/icons/time.png"></image>
								<text>{{ item.duration }}分钟</text>
							</view>
							<view class="price">
								<text class="symbol">¥</text>
								<text class="number">{{ item.price }}</text>
							</view>
						</view>
					</view>
				</view>
			</scroll-view>
		</view>
		<!-- 预约时间选择 -->
		<view class="booking-time">
			<view class="section-title">
				<text>选择时间</text>
				<text class="scroll-tip">可滚动查看更多</text>
			</view>
			<view class="date-list">
				<view class="date-item" v-for="(date, index) in availableDates" :key="index"
					:class="{ active: selectedDate === date.value }" @tap="fetchAvailableTimes(date)">
					<text class="day">{{ date.day }}</text>
					<text class="date">{{ date.text }}</text>
				</view>
			</view>
			<view class="time-slots" v-if="selectedDate">
				<view class="time-slot" v-for="slot in timeSlots" :key="slot.id" :class="{ 
						active: selectedTime === slot.time,
						disabled: !slot.available 
					}" @click="handleTimeSelect(slot)">
					<text class="time-text">{{ slot.time }}</text>
					<text style="font-size: 70%; color: #a6a6a6;">{{ slot.endTimeInfo + slot.duration }}</text>
				</view>
			</view>
		</view>
		<!-- <view class="remarks">
			<view class="additional-services" v-if="additionalServiceList.length > 0">
				<view class="section-title">附加项目</view>
				<view class="service-options">
					<view class="service-option" v-for="service in additionalServiceList" :key="service.id"
						:class="{ active: selectedAdditionalServices.includes(service.id) }"
						@tap="toggleAdditionalService(service)">
						<text class="service-name">{{ service.projectName }}</text>
						<text class="service-price">￥{{ service.price }}</text>
					</view>
				</view>
			</view>
		</view> -->
		<!-- 优惠券选择部分 -->
		<view class="coupon-section" v-if="serviceInfo.id">
			<view class="module-title">优惠券</view>
			<view class="coupon-list">
				<view class="coupon-item" v-for="coupon in availableCoupons" :key="coupon.id"
					:class="{ active: selectedCoupon && selectedCoupon.id === coupon.id }" @tap="selectCoupon(coupon)">
					<view class="coupon-info">
						<view class="coupon-name">{{ coupon.coupons.title }}</view>
						<view class="coupon-desc">{{ coupon.coupons.limitDesc }}</view>
						<view class="coupon-validity">有效期至：{{ coupon.expireTime }}</view>
					</view>
					<view class="coupon-amount">
						<text class="amount">￥{{ coupon.coupons.amount }}</text>
						<text class="condition" v-if="coupon.coupons.minAmount">满{{ coupon.coupons.minAmount }}可用</text>
					</view>
				</view>
				<view class="no-coupon" v-if="availableCoupons.length === 0">
					暂无可用优惠券
				</view>
			</view>
		</view>
		<!-- 会员卡选择部分 -->
		<view class="member-card-section" v-if="serviceInfo.id">
			<view class="module-title">会员卡</view>
			<view class="member-card-list">
				<view class="member-card-item" v-for="card in availableMemberCards" :key="card.id"
					:class="{ active: selectedMemberCard && selectedMemberCard.id === card.id }"
					@tap="selectMemberCard(card)">
					<view class="card-info">
						<view class="card-name">{{ card.memberCard.cardName }}</view>
						<view v-if="card.memberCard.cardType === 1" class="card-desc">
							余额：{{ card.balance }}元
						</view>
						<view v-if="card.memberCard.cardType === 2" class="card-desc">
							剩余次数：{{ card.remainingTimes }}次
						</view>
						<view class="card-validity">有效期至：{{ card.memberCard.expireTime }}</view>
					</view>
					<view class="card-action">
						<text class="action-text">
							{{ selectedMemberCard && selectedMemberCard.id === card.id ? '已选择' : '选择' }}
						</text>
					</view>
				</view>
				<view class="no-card" v-if="availableMemberCards.length === 0">
					暂无可用会员卡
				</view>
			</view>
		</view>
		<!-- 附赠项目列表 -->
		<view class="gift-service-list" v-if="selectedMemberCard && giftProject && giftProject.status === true">
			<view class="module-title">附赠项目</view>
			<text class="module-title">- 剩余次数：{{ giftProject.num }}</text>
			<text class="module-title">- 有效期至: {{ giftProject.expireTime }}</text>
			<view class="gift-list">
				<view class="gift-item" v-for="gift in giftProject.list" :key="gift.id" :class="{ 
						active: selectedGiftId === gift.id,
					}" @tap="selectGiftService(gift)">
					<view class="gift-info">
						<text class="name">{{ gift.projectName }}</text>
					</view>
					<view class="action">
						<text class="action-text">
							{{ selectedGiftId === gift.id ? '已选择' : '选择' }}
						</text>
					</view>
				</view>
			</view>
		</view>
		<!-- 备注信息 -->
		<view class="remarks">
			<view class="section-title">备注信息</view>
			<textarea class="remark-input" v-model="remarks" placeholder="请输入特殊需求或注意事项" maxlength="200"></textarea>
		</view>
		<view style="position: fixed;left: 0;right: 0;bottom: 5%;">
			<uni-notice-bar show-icon scrollable
				text="感谢您选择我们的服务，出于对顾客的权益保护，本平台禁止任何线下交易，顾客和技师之间只使用平台虚拟号进行线上联系，一旦发现技师违反平台规定向顾客索要联系方式或进行私下交易，凭相关证据（视频或照片或语音），顾客可获得平台免单及现金奖励。" />
		</view>
		<!-- 底部提交按钮 -->
		<view class="submit-section">
			<view class="price-info">
				<text class="label">总计</text>
				<text class="price">￥{{ totalPrice }}</text>
			</view>
			<view class="submit-btn" @click="showConfirmDialog" :class="{'disabled': isTechnician}"
				:style="isTechnician ? 'background: #CCCCCC; box-shadow: none;' : ''">
				<text>{{ isTechnician ? '技师账号不可预约' : '确认预约' }}</text>
			</view>
		</view>
		<!-- 小型确认弹窗 -->
		<view class="mini-confirm-dialog" v-if="showMiniConfirm">
			<view class="dialog-content">
				<view class="dialog-title">确认预约</view>
				<view class="dialog-text">是否确认预约该服务？</view>
				<view class="dialog-price">￥{{totalPrice}}</view>
				<view class="dialog-buttons">
					<button class="cancel-btn" @tap="cancelConfirm">取消</button>
					<button class="confirm-btn" @tap="handleSubmit">确认</button>
				</view>
			</view>
			<view class="dialog-mask" @tap="cancelConfirm"></view>
		</view>
	</view>
</template>
<script>
import NavBar from '@/components/nav-bar/nav-bar.vue';
import {request} from '@/utils/request.js';

export default {
		components: {
			NavBar
		},
		data() {
			return {
				giftProject: null,
				isTechnician: false, // 添加技师标识
				showUnselectedTips: true, // 添加未选择提示显示状态
				preSelectedServiceId: null, // 预选择的服务ID
				techInfo: {
					id: '',
					name: '',
					avatar: '',
					title: '',
					score: 0,
					orders: 0
				},
				serviceInfo: {
					id: '',
					name: '',
					price: 0,
					duration: 0
				},
				storeId: '',
				startDate: '',
				endDate: '',
				selectedDate: '',
				selectedTime: '',
				timeSlots: [],
				availableDates: [], // 添加可选日期数组
				currentHour: new Date().getHours(),
				remarks: '',
				// 新增地图相关数据
				mapInfo: {
					latitude: 39.909,
					longitude: 116.397,
				},
				storeInfo: {
					id: '',
					name: '',
					address: '',
					latitude: 0,
					longitude: 0,
					distance: ''
				},
				userLocation: {
					latitude: 0,
					longitude: 0
				},
				mapMarkers: [],
				// 修改为空数组，从接口获取数据
				serviceList: [],
				coupons: [], // 用户优惠券列表
				availableCoupons: [], // 可用优惠券列表
				selectedCoupon: null, // 选中的优惠券
				totalPrice: 0, // 添加总价字段
				memberCards: [], // 用户拥有的会员卡列表
				availableMemberCards: [], // 可用会员卡列表
				selectedMemberCard: null, // 选中的会员卡
				giftServices: [], // 添加附赠项目列表
				projectList: [], // 添加项目列表
				// 添加技师服务时间相关数据
				technicianServiceTimes: [], // 技师服务时间列表
				unavailableServiceTimes: [], // 不可用时间段列表
				// 微信JSSDK相关
				wxJssdkReady: false, // 微信JSSDK是否已准备好
				wxJssdkInitAttempts: 0, // 初始化尝试次数
				// 防止重复提交
				isSubmitting: false,
				selectedGiftId: null, // 添加选中的附赠项目ID
				selectedGift: null, // 添加选中的附赠项目
				showMiniConfirm: false, // 添加控制确认弹窗显示的状态
				additionalServiceList: [], // 附加项目列表
				selectedAdditionalServices: [], // 已选择的附加项目ID列表
				additionalServicesMap: {}, // 附加项目映射，用于快速查找价格
				isIOS: false
			}
		},
		watch: {
			selectedStoreIndex(val) {
				this.checkUnselectedItems()
			},
			serviceInfo: {
				handler(newVal) {
					this.updateAvailableCoupons()
					this.updateAvailableMemberCards()
					this.calculateTotalPrice()
					this.checkUnselectedItems()
				},
				deep: true,
				immediate: true
			},
			selectedDate(val) {
				this.checkUnselectedItems()
			},
			selectedTime(val) {
				this.checkUnselectedItems()
			},
			selectedCoupon: {
				handler(newVal) {
					this.calculateTotalPrice()
					// 如果选择了优惠券，取消会员卡选择
					if (newVal) {
						this.selectedMemberCard = null
					}
				},
				immediate: true
			},
			selectedMemberCard: {
				handler(newVal) {
					this.calculateTotalPrice()
					// 如果选择了会员卡，取消优惠券选择
					if (newVal) {
						this.selectedCoupon = null
					}
				},
				immediate: true
			}
		},
		computed: {
			// 获取服务时长
			serviceDuration() {
				return this.serviceInfo.duration || 0
			}
		},
		onLoad(options) {
			if (options.code) {
				this.editUserOpenid(options.code)
			}
			this.checkUserRole()
			// 保存预选择的服务ID
			this.preSelectedServiceId = options.preSelectedServiceId || null
			if (options.techId && options.serviceId && options.storeId) {
				this.loadTechInfo(options.techId)
				this.loadServiceInfo(options.techId)
				this.loadStoreInfo(options.storeId)
				this.storeId = options.storeId
				this.getUserLocation()
				this.initDateTime()
				// 加载用户优惠券
				this.loadUserCoupons()
				// 加载用户会员卡
				this.loadMemberCards()
				// 加载所有项目列表
				this.loadAllProjects()
				this.loadAdditionalServices() // 加载附加项目列表
			}
		},
		onShow() {
			this.checkUserRole()
		},
		mounted() {
			// 检测是否在微信环境中
			const isWeixinBrowser = /MicroMessenger/i.test(navigator.userAgent);
			if (isWeixinBrowser) {
				// 初始化微信JSSDK
				this.initWechatJssdk();
			}
		},
		methods: {
			editUserOpenid(code) {
				let userInfo = uni.getStorageSync('userInfo')
				if (!userInfo) {
					uni.reLaunch({
						url: '/pages/login/login'
					})
				}
				uni.request({
					url: `${uni.$config.baseUrl}/wx/wx-service/getOauth2AccessToken`,
					method: 'GET',
					data: {
						code
					},
					success: (res) => {
						if (res.statusCode === 200 && res.data.code === 200) {
							uni.request({
								url: `${uni.$config.baseUrl}/member/member/edit-open-id`,
								method: 'POST',
								data: {
									id: userInfo.memberId,
									openId: res.data.data.openid
								},
								success: (wxRes) => {
									if (wxRes.statusCode === 200 && wxRes.data.code === 200) {
										userInfo.openId = wxRes.data.data.openid
										uni.setStorageSync('userInfo', userInfo)
									}
								}
							})
						}
					}
				})
			},
			checkUserRole() {
				const userInfoStr = uni.getStorageSync('userInfo')
				let userInfo = null
				if (userInfoStr) {
					try {
						if (typeof userInfoStr === 'string') {
							const parsed = JSON.parse(userInfoStr)
							if (parsed.code === 200 && parsed.data) {
								userInfo = parsed.data
							} else {
								userInfo = parsed
							}
						} else {
							userInfo = userInfoStr
						}
						if (userInfo && userInfo.role === 'technician') {
							this.isTechnician = true
							uni.showModal({
								title: '提示',
								content: '您当前登录的账号为技师账号，不可预约',
								showCancel: false,
								confirmText: '知道了'
							})
						}
					} catch (e) {}
				}
			},
			// 初始化微信JSSDK
			initWechatJssdk() {
				// 先检查是否已经初始化
				if (this.wxJssdkReady) {
					return;
				}
				// 判断是否为开发环境
				const isDev = process.env.NODE_ENV === 'development';
				// 开发环境下直接进入配置阶段
				if (isDev) {
					this.configWechatJssdk();
					return;
				}
				// 记录初始化尝试次数
				this.wxJssdkInitAttempts = this.wxJssdkInitAttempts || 0;
				this.wxJssdkInitAttempts++;
				// 如果尝试次数过多，使用本地位置
				if (this.wxJssdkInitAttempts > 3) {
					this.useDefaultLocation();
					return;
				}
				// 动态加载微信JSSDK（如果未引入）
				this.loadWechatJSSdkScript();
			},
			// 加载微信JSSDK脚本
			loadWechatJSSdkScript() {
				// 检查JSSDK脚本是否已加载
				if (typeof wx !== 'undefined' && typeof wx.config === 'function') {
					this.configWechatJssdk();
					return;
				}
				// 尝试多个CDN源
				const cdnUrls = [
					'https://res2.wx.qq.com/open/js/jweixin-1.6.0.js',
					'https://res.wx.qq.com/open/js/jweixin-1.6.0.js',
					'https://cdn.jsdelivr.net/npm/jweixin-1.6.0/index.js' // 备用CDN
				];
				// 按顺序尝试各个CDN
				this.tryLoadFromCDNs(cdnUrls, 0);
			},
			// 从CDN列表中尝试加载
			tryLoadFromCDNs(cdnUrls, index) {
				// 如果已经尝试了所有CDN源
				if (index >= cdnUrls.length) {
					this.useDefaultLocation();
					return;
				}
				const url = cdnUrls[index];
				// 创建脚本元素
				const script = document.createElement('script');
				script.type = 'text/javascript'; // 确保类型正确
				script.charset = 'utf-8'; // 设置字符集
				script.async = true; // 异步加载
				script.src = url;
				// 加载成功回调
				script.onload = () => {
					// 验证wx对象
					if (typeof wx !== 'undefined' && typeof wx.config === 'function') {
						this.configWechatJssdk();
					} else {
						// 删除当前脚本标签
						script.parentNode.removeChild(script);
						// 尝试下一个CDN
						this.tryLoadFromCDNs(cdnUrls, index + 1);
					}
				};
				// 加载失败回调
				script.onerror = () => {
					// 删除当前脚本标签
					if (script.parentNode) {
						script.parentNode.removeChild(script);
					}
					// 尝试下一个CDN
					this.tryLoadFromCDNs(cdnUrls, index + 1);
				};
				// 添加到页面
				document.head.appendChild(script);
			},
			// 配置微信JSSDK
			async configWechatJssdk() {
				try {
					// 判断是否为开发环境
					const isDev = process.env.NODE_ENV === 'development';
					console.log('当前环境:', isDev ? '开发环境' : '生产环境');
					if (isDev) {
						// 开发环境 - 使用简化的测试流程
						// 确保wx对象存在
						if (typeof wx === 'undefined' || typeof wx.config !== 'function') {
							// 创建一个简单的模拟wx对象
							window.wx = {
								config: function(opts) {
									setTimeout(() => {
										if (typeof window.wx.readyCallback === 'function') {
											window.wx.readyCallback();
										}
									}, 500);
								},
								ready: function(callback) {
									window.wx.readyCallback = callback;
								},
								error: function(callback) {
									// 开发模式下不触发错误
								},
								getLocation: function(opts) {
									console.log('模拟wx.getLocation调用');
									if (opts && opts.success) {
										opts.success({
											latitude: 39.90923,
											longitude: 116.397428,
											speed: 0,
											accuracy: 10
										});
									}
								},
								openLocation: function(opts) {
									if (opts && opts.success) opts.success({});
								},
								chooseLocation: function(opts) {
									if (opts && opts.success) {
										opts.success({
											latitude: 39.90923,
											longitude: 116.397428,
											name: '测试位置',
											address: '北京市测试地址'
										});
									}
								}
							};
						}
						// 固定的测试配置
						const testConfig = {
							debug: true,
							appId: 'wxee39deb8d9fd37e3',
							timestamp: '' + Math.floor(Date.now() / 1000),
							nonceStr: 'test_nonce_str_' + Math.random().toString(36).substr(2, 8),
							signature: 'test_signature_' + Math.random().toString(36).substr(2, 8),
							jsApiList: [
								'getLocation',
								'openLocation',
								'chooseLocation'
							]
						};
						// 设置ready回调
						wx.ready(() => {
							this.wxJssdkReady = true;
							uni.showToast({
								title: '测试模式：JSSDK初始化成功',
								icon: 'none',
								duration: 1500
							});
						});
						// 调用config
						wx.config(testConfig);
						return;
					}
					// 生产环境下获取配置并调用真实API
					const url = location.href.split('#')[0];
					const result = await uni.request({
						url: `${uni.$config.baseUrl}/wx/jssdk/config`,
						method: 'GET',
						data: {
							url
						}
					});
					if (!result.data || result.data.code !== 200) {
						throw new Error(result.data ? result.data.msg || '获取JSSDK配置失败' : '获取JSSDK配置失败');
					}
					const config = result.data.data;
					wx.config({
						debug: false,
						appId: config.appId,
						timestamp: config.timestamp,
						nonceStr: config.nonceStr,
						signature: config.signature,
						jsApiList: ['getLocation', 'openLocation', 'chooseLocation']
					});
					wx.ready(() => {
						this.wxJssdkReady = true;
					});
					wx.error((error) => {
						this.wxJssdkReady = false;
						uni.showToast({
							title: 'JSSDK初始化失败',
							icon: 'none',
							duration: 1500
						});
						// 使用默认位置
						this.useDefaultLocation();
					});
				} catch (error) {
					uni.showToast({
						title: 'JSSDK初始化失败: ' + error.message,
						icon: 'none',
						duration: 3000
					});
					// 延迟后尝试重新加载JSSDK
					setTimeout(() => {
						this.initWechatJssdk();
					}, 3000);
				}
			},
			// 加载用户优惠券
			loadUserCoupons() {
				const userInfoStr = uni.getStorageSync('userInfo')
				let userInfo = null
				if (userInfoStr) {
					try {
						if (typeof userInfoStr === 'string') {
							const parsed = JSON.parse(userInfoStr)
							if (parsed.code === 200 && parsed.data) {
								userInfo = parsed.data
							} else {
								userInfo = parsed
							}
						} else {
							userInfo = userInfoStr
						}
					} catch (e) {
						userInfo = userInfoStr
					}
				}
				if (!userInfo || !userInfo.memberId) {
					return
				}
				uni.request({
					url: `${uni.$config.baseUrl}/usercoupons/usercoupons/listAllByUserId/${userInfo.memberId}`,
					method: 'GET',
					success: (res) => {
						if (res.statusCode === 200 && res.data && res.data.code === 200) {
							this.coupons = res.data.rows || []
							this.updateAvailableCoupons()
						}
					}
				})
			},
			// 选择优惠券
			selectCoupon(coupon) {
				if (this.selectedCoupon && this.selectedCoupon.id === coupon.id) {
					this.selectedCoupon = null
				} else {
					this.selectedCoupon = coupon
				}
			},
			// 加载用户会员卡
			loadMemberCards() {
				const userInfoStr = uni.getStorageSync('userInfo')
				let userInfo = null
				if (userInfoStr) {
					try {
						if (typeof userInfoStr === 'string') {
							const parsed = JSON.parse(userInfoStr)
							if (parsed.code === 200 && parsed.data) {
								userInfo = parsed.data
							} else {
								userInfo = parsed
							}
						} else {
							userInfo = userInfoStr
						}
					} catch (e) {
						userInfo = userInfoStr
					}
				}
				if (!userInfo || !userInfo.memberId) {
					return
				}
				uni.request({
					url: `${uni.$config.baseUrl}/usercard/usercard/listByUid`,
					method: 'GET',
					data: {
						memberId: userInfo.memberId
					},
					success: (res) => {
						if (res.statusCode === 200 && res.data && res.data.code === 200) {
							this.memberCards = res.data.rows || []
							this.updateAvailableMemberCards()
						}
					}
				})
			},
			// 更新可用会员卡列表
			updateAvailableMemberCards() {
				if (!this.serviceInfo || !this.serviceInfo.id) {
					this.availableMemberCards = []
					this.selectedMemberCard = null
					return
				}
				// 筛选可用会员卡
				this.availableMemberCards = this.memberCards.filter(card => {
					// 检查会员卡是否有效
					if (card.status !== 1 || card.isDeleted === 1) return false
					// 储值卡检查剩余金额
					if (card.memberCard.cardType === 1 && card.balance < this.totalPrice)
						return false
					// 次卡检查剩余次数
					if (card.memberCard.cardType === 2 && card.remainingTimes <= 0)
						return false
					// 检查项目是否可用
					if (card.memberCard && card.memberCard.projectIds) {
						return card.memberCard.projectIds.split(',').includes(this.serviceInfo.id.toString())
					}
					return false
				})
				// 如果当前选中的会员卡不可用，清除选择
				if (this.selectedMemberCard && !this.availableMemberCards.find(c => c.id === this.selectedMemberCard.id)) {
					this.selectedMemberCard = null
				}
			},
			// 选择会员卡
			selectMemberCard(card) {
				if (this.selectedMemberCard && this.selectedMemberCard.id === card.id) {
					this.selectedMemberCard = null
					this.giftServices = [] // 清空附赠项目
				} else {
					this.selectedMemberCard = card
					// 如果选择了会员卡，取消优惠券选择
					this.selectedCoupon = null
					if (card && card.cardId) {
						// 查询赠送项目列表
						request({
							url: `${uni.$config.baseUrl}/project/project/get-list-by-card-id`,
							method: 'GET',
							data: {
								cardId: card.cardId
							}
						}).then(res => {
							this.giftProject = {
								type: card.memberCard.cardType,
								balance: card.balance,
								status: card.giftProjectStatus,
								num: card.numberGiftItems,
								cardId: card.id,
								expireTime: card.memberCard.expireTime,
								list: res.data
							}
						})
					}
				}
			},
			getStartDate() {
				const date = new Date()
				return date.toISOString().split('T')[0]
			},
			getEndDate() {
				const date = new Date()
				date.setDate(date.getDate() + 2)
				return date.toISOString().split('T')[0]
			},
			async loadTechInfo(techId) {
				try {
					const res = await uni.request({
						url: `${uni.$config.baseUrl}/technician/technician/${techId}`,
						method: 'GET'
					})

					if (res.statusCode === 200 && res.data.code === 200) {
						const data = res.data.data
						console.log(res)
						this.techInfo = {
							id: data.id,
							name: data.name,
							avatar: data.avatar,
							title: data.title,
							score: data.score || 0,
							orders: data.appointmentCount || 0,
							storeId: data.storeId
						}

						// 如果已经选择了日期，获取技师服务时间
						if (this.selectedDate) {
							this.getTechnicianServiceTimes(this.techInfo.id, this.selectedDate)
						}
					} else {
						uni.showToast({
							title: '获取技师信息失败',
							icon: 'none'
						})
					}
				} catch (error) {
					console.error('获取技师信息失败:', error)
					uni.showToast({
						title: '获取技师信息失败',
						icon: 'none'
					})
				}
			},
			// 获取当前登录用户的memberId
			getCurrentMemberId() {
				const userInfoStr = uni.getStorageSync('userInfo')
				let userInfo = null

				if (userInfoStr) {
					try {
						// 如果是字符串，尝试解析
						if (typeof userInfoStr === 'string') {
							const parsed = JSON.parse(userInfoStr)
							// 检查是否是登录响应格式
							if (parsed.code === 200 && parsed.data) {
								userInfo = parsed.data
							} else {
								userInfo = parsed
							}
						} else {
							// 如果不是字符串，直接使用
							userInfo = userInfoStr
						}
					} catch (e) {
						console.error('解析用户信息失败', e)
						// 解析失败时，尝试直接使用
						userInfo = userInfoStr
					}
				}

				return userInfo ? userInfo.memberId : null
			},
			// 加载服务信息
			loadServiceInfo(techId) {
				uni.request({
					url: `${uni.$config.baseUrl}/project/project/technician/${techId}`,
					method: 'GET',
					success: (res) => {
						if (res.statusCode === 200 && res.data && res.data.code === 200) {
							const projectList = res.data.rows || []
							// 处理项目数据
							this.serviceList = projectList.map(project => ({
								id: project.id,
								name: project.projectName || '',
								duration: project.duration || 60,
								price: project.price || 0,
								img: project.imgUrls.split(',')[0],
								originalPrice: project.originalPrice || 0,
								projectDesp: project.projectDesp || ''
							}))
							// 如果有预选择的服务ID，自动选中该服务
							if (this.preSelectedServiceId) {
								const preSelectedService = this.serviceList.find(service =>
									service.id.toString() === this.preSelectedServiceId.toString()
								)
								if (preSelectedService) {
									this.selectService(preSelectedService)
								}
							}
						} else {
							// 设置默认项目列表
							this.serviceList = []
						}
					},
					fail: (err) => {
						this.serviceList = []
					}
				})
			},
			loadStoreInfo(storeId) {
				uni.showLoading({
					title: '加载中...'
				})

				// 使用提供的接口获取门店详细信息
				uni.request({
					url: `${uni.$config.baseUrl}/store/store/${storeId}`,
					method: 'GET',
					success: (res) => {
						if (res.statusCode === 200 && res.data && res.data.code === 200) {
							const storeData = res.data.data

							// 更新门店信息
							this.storeInfo = {
								id: storeData.id,
								name: storeData.storeName || storeData.name || '未知门店',
								address: storeData.address || '暂无地址',
								latitude: storeData.latitude || 39.909652,
								longitude: storeData.longitude || 116.397456,
								distance: this.storeInfo.distance || '',
								phone: storeData.contactPhone || ''
							}

							// 更新地图中心点
							this.mapInfo.latitude = this.storeInfo.latitude
							this.mapInfo.longitude = this.storeInfo.longitude

							// 更新地图标记
							this.updateMapMarkers()

							// 计算距离
							this.calculateDistance()

							console.log('门店信息加载成功:', this.storeInfo)
						} else {
							uni.showToast({
								title: res.data?.msg || '获取门店信息失败',
								icon: 'none'
							})

							// 使用默认数据
							this.storeInfo = {
								id: storeId,
								name: '康养SPA会所',
								address: '暂无地址信息',
								latitude: 39.909652,
								longitude: 116.397456
							}

							// 更新地图中心点和标记
							this.mapInfo.latitude = this.storeInfo.latitude
							this.mapInfo.longitude = this.storeInfo.longitude
							this.updateMapMarkers()
						}
					},
					fail: (err) => {
						console.error('获取门店信息失败:', err)
						uni.showToast({
							title: '网络请求失败，请检查网络',
							icon: 'none'
						})

						// 使用默认数据
						this.storeInfo = {
							id: storeId,
							name: '康养SPA会所',
							address: '暂无地址信息',
							latitude: 39.909652,
							longitude: 116.397456
						}

						// 更新地图中心点和标记
						this.mapInfo.latitude = this.storeInfo.latitude
						this.mapInfo.longitude = this.storeInfo.longitude
						this.updateMapMarkers()
					},
					complete: () => {
						uni.hideLoading()
					}
				})
			},
			getUserLocation() {
				// 检测是否在微信环境中
				const isWeixinBrowser = /MicroMessenger/i.test(navigator.userAgent);

				// 微信环境下使用微信JSSDK
				if (isWeixinBrowser && typeof wx !== 'undefined' && this.wxJssdkReady) {
					console.log('检测到微信环境，使用微信JSSDK获取位置');
					wx.getLocation({
						type: 'gcj02', // 使用国测局坐标系
						success: (res) => {
							console.log('微信定位成功:', res);
							this.userLocation.latitude = res.latitude;
							this.userLocation.longitude = res.longitude;
							this.calculateDistance();
							this.updateMapMarkers();
						},
						fail: (error) => {
							console.error('微信定位失败:', error);
							// // 处理微信定位失败的情况
							// uni.showModal({
							// 	title: '位置获取失败',
							// 	content: '请在微信中授权获取位置信息，或手动选择位置',
							// 	confirmText: '手动选择',
							// 	cancelText: '使用默认',
							// 	success: (res) => {
							// 		if (res.confirm) {
							// 			// 使用微信地图选择位置
							// 			wx.chooseLocation({
							// 				success: (res) => {
							// 					console.log('位置选择成功:', res);
							// 					this.userLocation.latitude = res.latitude;
							// 					this.userLocation.longitude = res.longitude;
							// 					this.calculateDistance();
							// 					this.updateMapMarkers();
							// 				},
							// 				fail: (error) => {
							// 					console.error('位置选择失败:', error);
							// 					this.useDefaultLocation();
							// 				},
							// 				cancel: () => {
							// 					console.log('用户取消选择位置');
							// 					this.useDefaultLocation();
							// 				}
							// 			});
							// 		} else {
							// 			// 使用默认位置
							// 			this.useDefaultLocation();
							// 		}
							// 	}
							// });
						}
					});
					return;
				}

				// 非微信环境或JSSDK未准备好，使用uni.getLocation
				// #ifdef H5
				if (navigator.geolocation) {
					navigator.geolocation.getCurrentPosition(
						(position) => {
							console.log('H5位置信息：', position);
							this.userLocation.latitude = position.coords.latitude;
							this.userLocation.longitude = position.coords.longitude;
							this.calculateDistance();
							this.updateMapMarkers();
						},
						(error) => {
							console.error('H5获取位置失败：', error);
							// // 当用户拒绝位置权限时，显示选择对话框
							// uni.showModal({
							// 	title: '位置获取失败',
							// 	content: '是否手动选择位置？',
							// 	confirmText: '选择位置',
							// 	cancelText: '使用默认',
							// 	success: (res) => {
							// 		if (res.confirm) {
							// 			// 使用地图选择位置
							// 			uni.chooseLocation({
							// 				success: (res) => {
							// 					this.userLocation.latitude = res.latitude;
							// 					this.userLocation.longitude = res.longitude;
							// 					this.calculateDistance();
							// 					this.updateMapMarkers();
							// 				},
							// 				fail: () => {
							// 					// 如果选择位置失败，使用默认位置
							// 					this.useDefaultLocation();
							// 				}
							// 			});
							// 		} else {
							// 			// 使用默认位置（北京市中心）
							// 			this.useDefaultLocation();
							// 		}
							// 	}
							// });
						}, {
							enableHighAccuracy: false, // 不需要高精度
							timeout: 5000, // 5秒超时
							maximumAge: 60000 // 允许使用最长1分钟的缓存位置
						}
					);
					return;
				}
				// #endif

				// 小程序或App环境下使用uni.getLocation
				uni.getLocation({
					type: 'gcj02',
					success: (res) => {
						console.log('uni位置信息：', res);
						this.userLocation.latitude = res.latitude;
						this.userLocation.longitude = res.longitude;
						this.calculateDistance();
						this.updateMapMarkers();
					},
					fail: (err) => {
						console.error('uni获取位置失败：', err);
						this.useDefaultLocation();
					}
				});
			},
			// 使用默认位置
			useDefaultLocation() {
				uni.showToast({
					title: '无法获取位置，使用默认位置',
					icon: 'none',
					duration: 2000
				});
				// 使用北京市中心作为默认位置
				this.userLocation.latitude = 39.909177;
				this.userLocation.longitude = 116.397451;
				this.calculateDistance();
				this.updateMapMarkers();
			},
			calculateDistance() {
				if (this.userLocation.latitude && this.storeInfo.latitude) {
					// 使用简单的距离计算公式（实际项目中建议使用更精确的计算方法）
					const distance = Math.sqrt(
						Math.pow(this.userLocation.latitude - this.storeInfo.latitude, 2) +
						Math.pow(this.userLocation.longitude - this.storeInfo.longitude, 2)
					) * 111 // 粗略转换为公里
					this.storeInfo.distance = distance.toFixed(1)
				}
			},
			updateMapMarkers() {
				this.mapMarkers = [{
					id: 1,
					latitude: this.storeInfo.latitude,
					longitude: this.storeInfo.longitude,
					title: this.storeInfo.name,
					iconPath: '/static/icons/store-marker.png', // 需要准备门店标记图标
					width: 32,
					height: 32
				}]
			},
			generateTimeSlots(selectedDate) {
				const today = new Date().toISOString().split('T')[0]
				const isToday = selectedDate === today
				const slots = []

				// 遍历10点到22点，每半小时一个选项
				for (let hour = 8; hour <= 24; hour++) {
					for (let minute = 0; minute < 60; minute += 30) {
						const timeString = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`
						let available = true

						if (isToday) {
							// 如果是当天，检查是否已过时间
							const currentHour = new Date().getHours()
							const currentMinutes = new Date().getMinutes()

							// 如果当前时间已经过了这个时间点，则不可选
							if (hour < currentHour || (hour === currentHour && minute <= currentMinutes)) {
								available = false
							}
						}

						// 检查服务结束时间是否超过营业时间（22:00）
						let endTimeInfo = ''
						if (this.serviceInfo.id) {
							const endTime = this.calculateEndTime(hour, minute, this.serviceDuration)
							endTimeInfo =
								`至 ${endTime.hour.toString().padStart(2, '0')}:${endTime.minute.toString().padStart(2, '0')}`
						}

						// 检查是否已经存在相同的时间段
						const existingSlot = slots.find(slot => slot.time === timeString)
						if (!existingSlot) {
							slots.push({
								time: timeString,
								available: available,
								endTimeInfo: endTimeInfo,
								duration: this.serviceDuration
							})
						}
					}
				}

				// this.timeSlots = slots

				// 如果之前选择的时间变为不可用，清除选择
				if (this.selectedTime) {
					const selectedSlot = slots.find(slot => slot.time === this.selectedTime)
					if (!selectedSlot?.available) {
						this.selectedTime = ''
					}
				}
			},
			calculateEndTime(startHour, startMinute, durationMinutes) {
				const totalMinutes = startHour * 60 + startMinute + durationMinutes
				const endHour = Math.floor(totalMinutes / 60)
				const endMinute = totalMinutes % 60
				return {
					hour: endHour,
					minute: endMinute
				}
			},
			initDateTime() {
				// 设置可选日期（今天、明天、后天）
				const dates = []
				const dayNames = ['今天', '明天', '后天']

				for (let i = 0; i < 3; i++) {
					const date = new Date()
					date.setDate(date.getDate() + i)
					dates.push({
						value: this.formatDate(date),
						text: `${date.getMonth() + 1}月${date.getDate()}日`,
						day: dayNames[i]
					})
				}
				this.availableDates = dates

				this.startDate = this.getStartDate()
				this.endDate = this.getEndDate()
				// this.selectedDate = this.startDate

				// 如果已经选择了技师，获取技师服务时间
				// if (this.techInfo.id) {
				this.getTechnicianServiceTimes(this.techInfo.id, this.selectedDate)
				// } else {
				// 	// 如果没有选择技师，使用默认方法生成时间槽
				// 	this.generateTimeSlots(this.selectedDate)
				// }
			},
			// 添加格式化日期的方法
			formatDate(date) {
				const year = date.getFullYear()
				const month = String(date.getMonth() + 1).padStart(2, '0')
				const day = String(date.getDate()).padStart(2, '0')
				return `${year}-${month}-${day}`
			},
			// 选择日期的方法
			selectDate(date) {
				// 兼容旧调用，直接转到 fetchAvailableTimes
				this.fetchAvailableTimes(date)
			},
			// 新增：调用后端接口获取可用时间段
			fetchAvailableTimes(dateObj) {
				this.selectedDate = dateObj.value
				this.selectedTime = ''
				this.timeSlots = []
				// 若未选技师或服务，退回旧逻辑
				if (!this.techInfo.id || !this.serviceInfo.duration) {
					this.generateTimeSlots(this.selectedDate)
					return
				}

				uni.request({
					url: `${uni.$config.baseUrl}/servicetime/servicetime/get-server-time-list`,
					method: 'POST',
					header: {
						'content-type': 'application/json'
					},
					data: {
						date: dateObj.value,
						techId: this.techInfo.id,
						duration: this.serviceInfo.duration,
					},
					success: (res) => {
						if (res.statusCode === 200 && res.data.code === 200) {
							const raw = res.data.data || []
							this.timeSlots = raw.map(item => ({
								id: item.timePoint,
								time: item.timePoint,
								endTimeInfo: item.endTimePoint || '',
								duration: item.duration,
								available: !item.disabled
							}))
						} else {
							// 回退到旧逻辑
							this.generateTimeSlots(this.selectedDate)
						}
					},
					fail: () => {
						this.generateTimeSlots(this.selectedDate)
					}
				})
			},
			handleTimeSelect(slot) {
				if (slot.available) {
					this.selectedTime = slot.time
				}
			},
			// 更新优惠券状态
			updateCouponStatus(coupon) {
				try {
					const updateData = {
						id: coupon.id,
						status: 2, // 2-已使用
						useTime: new Date().toISOString()
					}

					const res = uni.request({
						url: `${uni.$config.baseUrl}/usercoupons/usercoupons/update`,
						method: 'POST',
						data: updateData
					})

					if (res.statusCode === 200 && res.data.code === 200) {
						console.log('优惠券状态更新成功')
						// 更新本地优惠券数据
						this.loadUserCoupons()
					} else {
						console.error('优惠券状态更新失败:', res.data.msg)
					}
				} catch (error) {
					console.error('更新优惠券状态异常:', error)
				}
			},
			// 减少附赠项目次数
			decreaseGiftServiceTimes() {
				if (!this.selectedGiftId) {
					return;
				}

				uni.request({
					url: `${uni.$config.baseUrl}/cardgiftuser/cardgiftuser/decreaseTimes`,
					method: 'POST',
					data: {
						id: this.selectedGiftId,
						times: 1, // 每次减少1次
						memberId: this.getCurrentMemberId() // 使用统一方法获取memberId
					},
					success: (res) => {
						if (res.data.code === 200) {
							console.log('减少附赠项目次数成功:', this.selectedGiftId);
						} else {
							console.error('减少附赠项目次数失败:', res.data.msg);
						}
					},
					fail: (err) => {
						console.error('减少附赠项目次数请求失败:', err);
					}
				});
			},
			// 减少会员卡次数或金额
			decreaseCardTimes() {
				if (!this.selectedMemberCard || !this.selectedMemberCard.id) {
					return;
				}

				// 根据会员卡类型决定是减少次数还是减少金额
				if (this.selectedMemberCard.memberCard.cardType === 1) {
					// 充值卡类型，减少金额
					this.decreaseCardBalance();
				} else {
					// 次卡类型，减少次数
					this.decreaseCardTimesOnly();
				}
			},
			// 减少会员卡次数
			decreaseCardTimesOnly() {
				if (!this.selectedMemberCard || !this.selectedMemberCard.id) {
					return;
				}

				uni.request({
					url: `${uni.$config.baseUrl}/usercard/usercard/decreaseTimes`,
					method: 'POST',
					data: {
						id: this.selectedMemberCard.id,
						times: 1, // 每次减少1次
						memberId: this.getCurrentMemberId() // 使用统一方法获取memberId
					},
					success: (res) => {
						if (res.data.code === 200) {
							console.log('减少会员卡次数成功:', this.selectedMemberCard.id);
						} else {
							console.error('减少会员卡次数失败:', res.data.msg);
						}
					},
					fail: (err) => {
						console.error('减少会员卡次数请求失败:', err);
					}
				});
			},
			// 减少会员卡余额
			decreaseCardBalance() {
				if (!this.selectedMemberCard || !this.selectedMemberCard.id) {
					return;
				}

				// 获取已选择的服务信息
				const selectedServiceInfo = this.services.find(s => s.id === this.selectedService);
				if (!selectedServiceInfo) {
					return;
				}

				// 计算需要扣除的金额
				const deductAmount = selectedServiceInfo.price;

				uni.request({
					url: `${uni.$config.baseUrl}/usercard/usercard/decreaseBalance`,
					method: 'POST',
					data: {
						id: this.selectedMemberCard.id,
						amount: deductAmount, // 扣除服务价格
						memberId: this.getCurrentMemberId() // 使用统一方法获取memberId
					},
					success: (res) => {
						if (res.data.code === 200) {
							console.log('减少会员卡余额成功:', this.selectedMemberCard.id, '扣除金额:', deductAmount);
						} else {
							console.error('减少会员卡余额失败:', res.data.msg);
						}
					},
					fail: (err) => {
						console.error('减少会员卡余额请求失败:', err);
					}
				});
			},
			handleSubmit() {
				// 防止重复提交
				if (this.isSubmitting) {
					uni.showToast({
						title: '请勿重复提交',
						icon: 'none'
					})
					return
				}
				// 检查是否是技师账号
				if (this.isTechnician) {
					uni.showModal({
						title: '提示',
						content: '您当前登录的账号为技师账号，不可预约',
						showCancel: false,
						confirmText: '知道了'
					})
					return
				}
				// 检查所有必要信息是否已选择
				if (!this.techInfo.id) {
					uni.showToast({
						title: '请选择技师',
						icon: 'none'
					})
					return
				}
				if (!this.serviceInfo.id) {
					uni.showToast({
						title: '请选择服务项目',
						icon: 'none'
					})
					return
				}
				if (!this.selectedDate) {
					uni.showToast({
						title: '请选择预约日期',
						icon: 'none'
					})
					return
				}
				if (!this.selectedTime) {
					uni.showToast({
						title: '请选择预约时间',
						icon: 'none'
					})
					return
				}
				const userInfo = uni.getStorageSync('userInfo')
				if (!userInfo.openId) {
					uni.showModal({
						title: '微信授权提示',
						content: '首次支付需要绑定微信账号，是否立即前往授权？',
						confirmText: '去授权',
						cancelText: '取消',
						success: res => {
							if (res.confirm) {
								const currentUrl = encodeURIComponent(window.location.href);
								const appId = uni.$config.wxAppId;
								const redirectUrl =
									`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${currentUrl}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`;
								window.location.href = redirectUrl;
							}
						},
						fail: (err) => {
							uni.showToast({
								title: JSON.stringify(err),
								icon: 'none',
								duration: 2000
							});
						},
					});
					return
				}
				// 设置为正在提交
				this.isSubmitting = true
				// 构建预约订单数据
				const appointmentOrders = {
					userId: userInfo.memberId,
					orderType: 1, // 1-预约到店
					img: this.serviceInfo.img,
					serviceId: this.serviceInfo.id,
					serviceName: this.serviceInfo.name,
					servicePrice: this.serviceInfo.price,
					serviceDuration: this.serviceInfo.duration,
					// 技师信息
					technicianId: this.techInfo.id,
					technicianName: this.techInfo.name,
					// 预约时间信息
					appointmentDate: this.selectedDate,
					appointmentTime: this.selectedTime + ":00",
					// 门店信息
					storeId: this.storeId,
					storeName: this.storeInfo.name,
					storeAddress: this.storeInfo.address,
					// 订单状态
					orderStatus: this.selectedMemberCard ? 1 : 0,
					paymentStatus: this.selectedMemberCard ? 1 : 0, // 会员卡支付时为1（已支付），否则为0（未支付）
					paymentAmount: this.totalPrice,
					// 备注信息
					remark: this.remarks.trim(),
					// 优惠券和会员卡ID
					couponId: this.selectedCoupon ? this.selectedCoupon.id : null,
					cardId: this.selectedMemberCard ? this.selectedMemberCard.id : null,
					// 附赠项目ID
					giftServiceId: this.selectedGiftId ? this.selectedGiftId : null,
					// 添加附加服务信息
					additionalService: this.selectedAdditionalServices.map(id => {
						const service = this.additionalServicesMap[id]
						return service.projectName
					}).join(','),
				}
				// 显示加载中
				uni.showLoading({
					title: '提交中...'
				})
				if (appointmentOrders.couponId) {
					if (!this.selectedCoupon.coupons.amount) {
						uni.showToast({
							title: '会员卡暂无金额',
							icon: 'error',
							duration: 2000
						})
						return
					}
					const amount = appointmentOrders.paymentAmount - this.selectedCoupon.coupons.amount
					appointmentOrders.paymentAmount = amount < 0 ? 0 : amount
					appointmentOrders.orderStatus = 1
					appointmentOrders.paymentStatus = 1
				}
				// 调用后端接口
				uni.request({
					url: `${uni.$config.baseUrl}/orders/orders`,
					method: 'POST',
					data: appointmentOrders,
					success: (res) => {
						if (res.statusCode === 200 && res.data.code === 200) {
							let orderid = res.data.data
							// 如果使用了优惠券，更新优惠券状态
							if (this.selectedCoupon) {
								if (appointmentOrders.paymentAmount <= 0) {
									setTimeout(() => {
										uni.navigateTo({
											url: '/pages/my-orders/my-orders'
										})
									}, 2000)
								}
								return
							}
							// 如果使用会员卡，不需要调用支付接口，直接跳转到订单页面
							if (this.selectedMemberCard) {
								uni.showToast({
									title: '预约成功',
									icon: 'success',
									duration: 2000,
									success: () => {
										setTimeout(() => {
											uni.navigateTo({
												url: '/pages/my-orders/my-orders'
											})
										}, 2000)
									}
								})
								// 会员卡支付情况下重置提交状态
								this.isSubmitting = false
								return
							}
							// 调用微信支付接口
							uni.request({
								url: `${uni.$config.baseUrl}/orders/orders/createWxPayOrder/${orderid}`,
								method: 'POST',
								success: (payRes) => {
									if (payRes.statusCode === 200 && payRes.data.code === 200) {
										let payData = payRes.data.data
										try {
											// 检查当前环境是否支持微信支付
											// #ifdef MP-WEIXIN
											// 小程序环境，直接调用支付接口
											this.callWxPayment(payData, orderid);
											// #endif

											// #ifdef H5
											// H5环境需要判断是否在微信浏览器中
											const isWechatBrowser = /MicroMessenger/i.test(
												navigator.userAgent);
											if (isWechatBrowser) {
												// 微信浏览器中，使用WeixinJSBridge调用支付
												this.callWechatH5Pay(payData, orderid);
											} else {
												// 非微信浏览器，提示用户
												uni.showModal({
													title: '提示',
													content: '微信支付需要在微信浏览器中打开，请复制链接到微信打开',
													showCancel: false,
													success: () => {
														// 重置提交状态
														this.isSubmitting = false;
													}
												});
											}
											// #endif

											// #ifdef APP-PLUS || APP-NVUE
											// App环境
											this.callAppPayment(payData, orderid);
											// #endif

											// #ifndef MP-WEIXIN || H5 || APP-PLUS || APP-NVUE
											// 其他环境（如开发环境）
											uni.showModal({
												title: '开发环境提示',
												content: '当前环境不支持微信支付功能，仅在微信环境中可用。是否模拟支付成功？',
												confirmText: '模拟成功',
												cancelText: '模拟失败',
												success: (res) => {
													if (res.confirm) {
														// 模拟支付成功
														uni.showToast({
															title: '支付成功(模拟)',
															icon: 'success',
															duration: 2000,
															success: () => {
																setTimeout(
																	() => {
																		uni.navigateTo({
																			url: '/pages/my-orders/my-orders'
																		})
																	},
																	2000
																)
															}
														});
													} else {
														// 模拟支付失败
														uni.showToast({
															title: '支付取消(模拟)',
															icon: 'none'
														});
													}
													// 重置提交状态
													this.isSubmitting = false;
												}
											});
											// #endif
										} catch (error) {
											console.error('支付环境错误:', error)
											let errorMsg = error.message || '支付功能初始化失败'

											// 特殊处理 "API requestPayment is not yet implemented" 错误
											if (errorMsg.includes(
													'requestPayment is not yet implemented')) {
												errorMsg = '当前环境不支持微信支付功能，请在微信环境中使用。'
											}

											uni.showModal({
												title: '支付提示',
												content: errorMsg,
												showCancel: false,
												success: () => {
													this.isSubmitting = false;
												}
											})
										}
									} else {
										uni.showToast({
											title: payRes.data.msg || '支付创建失败',
											icon: 'none'
										})
										// 支付创建失败时重置提交状态
										this.isSubmitting = false
									}
								},
								fail: (err) => {
									console.error('调用支付接口失败:', err)
									uni.showToast({
										title: '支付创建失败',
										icon: 'none'
									})
									// 支付接口调用失败后重置提交状态
									this.isSubmitting = false
								}
							})
						} else {
							uni.showToast({
								title: res.data.msg || '预约失败',
								icon: 'none'
							})
							// 订单创建失败，重置提交状态
							this.isSubmitting = false
						}
					},
					fail: (err) => {
						console.error('预约失败:', err)
						uni.showToast({
							title: '网络请求失败',
							icon: 'none'
						})
						// 网络请求失败，重置提交状态
						this.isSubmitting = false
					},
					complete: () => {
						uni.hideLoading()
						// 如果是会员卡支付，在complete中确保重置状态
						if (this.selectedMemberCard) {
							this.isSubmitting = false
						}
					}
				})
			},
			// 选择服务项目
			selectService(service) {
				this.serviceInfo = {
					id: service.id,
					name: service.name,
					price: service.price,
					duration: service.duration,
					img: service.img
				}
				// 重新生成时间槽，以更新结束时间信息
				if (this.selectedDate) {
					// 如果已获取了技师服务时间，使用技师服务时间生成时间槽
					if (this.technicianServiceTimes.length > 0) {
						this.generateTimeSlotsFromServiceTimes()
					} else {
						this.generateTimeSlots(this.selectedDate)
					}
				}
				// 更新优惠券和会员卡
				this.updateAvailableCoupons()
				this.updateAvailableMemberCards()
			},
			// 计算总价（包含优惠券和会员卡 ）
			calculateTotalPrice() {
				let total = 0

				// 添加主服务费用
				if (this.serviceInfo && this.serviceInfo.price) {
					total += this.serviceInfo.price
				}

				// 添加附加项目费用
				this.selectedAdditionalServices.forEach(serviceId => {
					const service = this.additionalServicesMap[serviceId]
					if (service) {
						total += service.price
					}
				})

				// 如果选择了会员卡，只收取附加项目费用
				if (this.selectedMemberCard) {
					total = this.selectedAdditionalServices.reduce((sum, serviceId) => {
						const service = this.additionalServicesMap[serviceId]
						return sum + (service ? service.price : 0)
					}, 0)
				} else if (this.selectedCoupon && this.selectedCoupon.coupons) {
					// 应用优惠券
					total = Math.max(0, total - this.selectedCoupon.coupons.amount)
				}

				this.totalPrice = total
			},
			// 更新可用优惠券列表
			updateAvailableCoupons() {
				if (!this.serviceInfo) {
					this.availableCoupons = []
					this.selectedCoupon = null
					return
				}

				const selectedServiceInfo = this.serviceList.find(s => s.id === this.serviceInfo.id)
				if (!selectedServiceInfo) {
					this.availableCoupons = []
					this.selectedCoupon = null
					return
				}

				// 筛选可用优惠券
				this.availableCoupons = this.coupons.filter(coupon => {
					console.log(coupon)
					// 检查优惠券是否过期
					const now = new Date()
					// 将 "2025-03-21 12:00:00" 格式的字符串转换为 Date 对象
					const dateString = coupon.coupons.validityEnd;


					// 拆分日期和时间部分
					const [datePart, timePart] = dateString.split(' ');
					const [year, month, day] = datePart.split('-').map(Number);
					const [hours, minutes, seconds] = timePart.split(':').map(Number);

					// 构造 Date 对象（注意：月份从 0 开始，需减 1）
					const expireDate = new Date(year, month - 1, day, hours, minutes, seconds);
					console.log(expireDate)
					console.log(now)
					//   const expireDate = new Date(coupon.coupons.validityEnd.replace(/-/g, '/'))
					if (now > expireDate) return false

					// 检查优惠券是否已使用
					if (coupon.coupons.status !== 1) return false

					// 检查优惠券是否适用于当前服务
					if (coupon.coupons && coupon.coupons.projectIds) {
						const projectIds = coupon.coupons.projectIds.split(',')
						if (!projectIds.includes(this.serviceInfo.id.toString())) return false
					}

					// 检查订单金额是否满足优惠券使用条件
					if (coupon.coupons && coupon.coupons.minAmount && selectedServiceInfo.price < coupon.coupons
						.minAmount) return false

					return true
				})

				// 如果当前选中的优惠券不可用，清除选择
				if (this.selectedCoupon && !this.availableCoupons.find(c => c.id === this.selectedCoupon.id)) {
					this.selectedCoupon = null
				}
			},
			// 获取技师服务时间
			async getTechnicianServiceTimes(technicianId, serviceDate) {
				uni.showLoading({
					title: '加载中...'
				})

				try {
					// 第一步：尝试从技师服务时间表获取数据
					const res = await uni.request({
						url: `${uni.$config.baseUrl}/servicetime/servicetime/listAll`,
						method: 'GET',
						data: {
							techId: technicianId,
							serviceDate: serviceDate // 格式为yyyy-MM-dd
						}
					})

					// 检查是否成功获取数据
					if (res.statusCode === 200 && res.data.code === 200) {
						// 如果获取到了数据
						if (res.data.rows && res.data.rows.length > 0) {
							// 保存技师服务时间数据
							this.technicianServiceTimes = res.data.rows || []

							// 解析不可用时间段
							this.parseUnavailableServiceTimes()

							// 根据服务时间生成时间槽
							this.generateTimeSlotsFromServiceTimes()

							console.log('获取技师服务时间成功:', this.technicianServiceTimes)
							uni.hideLoading()
							return
						} else {
							console.log('技师服务时间为空，尝试获取技师工作排班...')
							// 如果没有获取到数据，尝试获取技师工作排班
							await this.getTechnicianWorkSchedule(technicianId, serviceDate)
						}
					} else {
						console.error('获取技师服务时间失败:', res.data.msg)
						// 尝试获取技师工作排班
						await this.getTechnicianWorkSchedule(technicianId, serviceDate)
					}
				} catch (error) {
					console.error('获取技师服务时间异常:', error)
					// 尝试获取技师工作排班
					await this.getTechnicianWorkSchedule(technicianId, serviceDate)
				} finally {
					uni.hideLoading()
				}
			},
			// 获取技师工作排班
			async getTechnicianWorkSchedule(technicianId, serviceDate) {
				try {
					const res = await uni.request({
						url: `${uni.$config.baseUrl}/schedule/schedule/listAll`,
						method: 'GET',
						data: {
							technicianId: technicianId,
							serviceDate: serviceDate // 格式为yyyy-MM-dd
						}
					})

					if (res.statusCode === 200 && res.data.code === 200 && res.data.rows && res.data.rows.length > 0) {
						console.log('获取技师工作排班成功:', res.data.rows)

						// 将工作排班数据转换为服务时间格式
						this.technicianServiceTimes = res.data.rows.map(schedule => {
							return {
								startTime: schedule.startTime,
								endTime: schedule.endTime,
								workDays: schedule.workDays,
								serviceDuration: '', // 工作排班没有已预约时间
								servicedDuration: '' // 工作排班没有技师设置的不可服务时间
							}
						})

						// 根据服务时间生成时间槽
						this.generateTimeSlotsFromServiceTimes()
					} else {
						console.error('获取技师工作排班失败或为空:', res.data.msg)
						this.technicianServiceTimes = []
						this.unavailableServiceTimes = []

						// 使用默认方法生成时间槽
						this.generateTimeSlots(this.selectedDate)
					}
				} catch (error) {
					console.error('获取技师工作排班异常:', error)
					this.technicianServiceTimes = []
					this.unavailableServiceTimes = []

					// 使用默认方法生成时间槽
					this.generateTimeSlots(this.selectedDate)
				}
			},
			// 解析不可用的时间段
			parseUnavailableServiceTimes() {
				this.unavailableServiceTimes = []

				if (!this.technicianServiceTimes || this.technicianServiceTimes.length === 0) return

				for (const serviceTime of this.technicianServiceTimes) {
					// 解析serviceDuration（已经预约的时间段）
					if (serviceTime.serviceDuration) {
						const times = serviceTime.serviceDuration.split(',')
						this.unavailableServiceTimes.push(...times)
					}

					// 解析servicedDuration（技师自己设置的不可服务时间段）
					if (serviceTime.servicedDuration) {
						const times = serviceTime.servicedDuration.split(',')
						this.unavailableServiceTimes.push(...times)
					}
				}

				// 去重
				this.unavailableServiceTimes = [...new Set(this.unavailableServiceTimes)]
				console.log('不可用时间段:', this.unavailableServiceTimes)
			},
			// 根据技师服务时间生成时间槽
			generateTimeSlotsFromServiceTimes() {
				const today = new Date().toISOString().split('T')[0]
				const isToday = this.selectedDate === today
				const currentHour = new Date().getHours()
				const currentMinute = new Date().getMinutes()
				const slots = []

				// 检查是否有服务时间数据
				if (!this.technicianServiceTimes || this.technicianServiceTimes.length === 0) {
					// 如果没有数据，使用默认方法生成时间槽
					this.generateTimeSlots(this.selectedDate)
					return
				}

				// 遍历每个服务时间记录
				for (const serviceTime of this.technicianServiceTimes) {
					if (serviceTime.startTime && serviceTime.endTime) {
						// 解析开始和结束时间
						const [startHour, startMinute] = serviceTime.startTime.split(':').map(Number)
						const [endHour, endMinute] = serviceTime.endTime.split(':').map(Number)

						// 计算开始和结束时间（分钟）
						const startTotalMinutes = startHour * 60 + startMinute
						const endTotalMinutes = endHour * 60 + endMinute

						// 生成从开始到结束时间的时间槽，每30分钟一个
						for (let totalMinutes = startTotalMinutes; totalMinutes <= endTotalMinutes; totalMinutes += 30) {
							const hour = Math.floor(totalMinutes / 60)
							const minute = totalMinutes % 60
							const timeString = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`

							// 检查是否是过去的时间（如果是今天）
							let available = true
							if (isToday && (hour < currentHour || (hour === currentHour && minute <= currentMinute))) {
								available = false
							}

							// 检查是否在不可用时间列表中
							if (this.unavailableServiceTimes.includes(timeString)) {
								available = false
							}

							// 检查服务结束时间是否超过服务结束时间
							let endTimeInfo = ''
							if (this.serviceInfo.id && this.serviceDuration > 0) {
								const endTime = this.calculateEndTime(hour, minute, this.serviceDuration)
								endTimeInfo =
									`至 ${endTime.hour.toString().padStart(2, '0')}:${endTime.minute.toString().padStart(2, '0')}`
							}

							// 检查是否已经存在相同的时间段
							const existingSlot = slots.find(slot => slot.time === timeString)
							if (!existingSlot) {
								slots.push({
									time: timeString,
									available: available,
									endTimeInfo: endTimeInfo,
									duration: this.serviceDuration
								})
							}
						}
					}
				}

				// 按时间排序
				slots.sort((a, b) => {
					const [aHour, aMinute] = a.time.split(':').map(Number)
					const [bHour, bMinute] = b.time.split(':').map(Number)
					return (aHour * 60 + aMinute) - (bHour * 60 + bMinute)
				})

				// this.timeSlots = slots

				// 如果之前选择的时间变为不可用，清除选择
				if (this.selectedTime) {
					const selectedSlot = slots.find(slot => slot.time === this.selectedTime)
					if (!selectedSlot || !selectedSlot.available) {
						this.selectedTime = ''
					}
				}

				// 如果没有可用时间，显示提示
				if (slots.length === 0 || !slots.some(slot => slot.available)) {
					uni.showToast({
						title: '该日期没有可用时间',
						icon: 'none'
					})
				}
			},
			// 加载所有项目列表
			loadAllProjects() {
				uni.request({
					url: `${uni.$config.baseUrl}/project/project/listAll`,
					method: 'GET',
					data: {
						status: 1
					},
					success: (res) => {
						if (res.statusCode === 200 && res.data && res.data.code === 200) {
							this.projectList = res.data.rows || []
						} else {
							console.error('获取项目列表失败:', res.data.msg)
						}
					},
					fail: (err) => {
						console.error('获取项目列表失败:', err)
					}
				})
			},
			// 根据项目ID获取项目名称
			getProjectName(projectId) {
				const project = this.projectList.find(p => p.id === projectId)
				return project ? project.projectName : '未知项目'
			},
			/**
			 * 小程序环境支付方法
			 * @param {Object} payData 支付参数
			 * @param {String} orderId 订单ID
			 */
			callWxPayment(payData, orderId) {
				uni.requestPayment({
					...payData,
					success: () => {
						uni.showToast({
							title: '支付成功',
							icon: 'success',
							duration: 2000,
							success: () => {
								setTimeout(() => {
									uni.navigateTo({
										url: '/pages/my-orders/my-orders'
									})
								}, 2000)
							}
						})
						// 更新订单支付状态
						this.updateOrderPaymentStatus(orderId, 1);
					},
					fail: (err) => {
						console.error('支付失败:', err)
						if (err.errMsg.indexOf('cancel') !== -1) {
							uni.showToast({
								title: '支付已取消，可在全部订单中查看',
								icon: 'none'
							})
						} else {
							uni.showToast({
								title: '支付失败',
								icon: 'none'
							})
						}
						this.isSubmitting = false
					},
					complete: () => {
						// 确保在任何情况下都重置提交状态
						this.isSubmitting = false
					}
				})
			},
			/**
			 * H5环境支付方法（微信浏览器中）
			 * @param {Object} payData 支付参数
			 * @param {String} orderId 订单ID
			 */
			callWechatH5Pay(payData, orderId) {
				if (typeof WeixinJSBridge === 'undefined') {
					document.addEventListener('WeixinJSBridgeReady', () => {
						this.onWeixinJSBridgeReady(payData, orderId);
					}, false);
					uni.showToast({
						title: '请在微信内完成支付',
						icon: 'none'
					});
					this.isSubmitting = false;
					return;
				}

				this.onWeixinJSBridgeReady(payData, orderId);
			},
			// WeixinJSBridge回调处理
			onWeixinJSBridgeReady(payData, orderId) {
				WeixinJSBridge.invoke(
					'getBrandWCPayRequest', {
						"appId": payData.appId,
						"timeStamp": payData.timeStamp,
						"nonceStr": payData.nonceStr,
						"package": payData.package,
						"signType": "RSA",
						"paySign": payData.paySign
					},
					(res) => {
						console.log('微信支付返回结果:', res);

						if (res.err_msg === "get_brand_wcpay_request:ok") {
							// 支付成功
							uni.showToast({
								title: '支付成功',
								icon: 'success',
								duration: 2000,
								success: () => {
									setTimeout(() => {
										uni.navigateTo({
											url: '/pages/my-orders/my-orders'
										})
									}, 2000)
								}
							});

							// 更新订单支付状态
							this.updateOrderPaymentStatus(orderId, 1);
						} else if (res.err_msg === "get_brand_wcpay_request:cancel") {
							// 用户取消支付
							uni.showToast({
								title: '支付已取消，可在全部订单中查看',
								icon: 'none'
							});
							this.isSubmitting = false;
						} else {
							// 支付失败
							uni.showToast({
								title: '支付失败',
								icon: 'none'
							});
							console.error('微信支付失败:', res.err_msg);
							this.isSubmitting = false;
						}
					}
				);
			},

			// 更新订单支付状态
			updateOrderPaymentStatus(orderId, paymentStatus) {
				if (!orderId) {
					console.error('订单ID不能为空')
					return
				}

				uni.request({
					url: `${uni.$config.baseUrl}/orders/orders/updatePaymentStatus`,
					method: 'POST',
					data: {
						orderId: orderId,
						paymentStatus: paymentStatus
					},
					success: (res) => {
						if (res.statusCode === 200 && res.data.code === 200) {
							console.log('订单支付状态更新成功')
						} else {
							console.error('订单支付状态更新失败:', res.data.message || '未知错误')
						}
					},
					fail: (err) => {
						console.error('更新订单支付状态请求失败:', err)
					}
				})
			},

			/**
			 * APP环境支付方法
			 * @param {Object} payData 支付参数
			 * @param {String} orderId 订单ID
			 */
			callAppPayment(payData, orderId) {
				plus.payment.getChannels(channels => {
					const wxChannel = channels.find(channel => channel.id === 'wxpay')
					if (wxChannel) {
						plus.payment.request(wxChannel, payData.paymentData, result => {
							uni.showToast({
								title: '支付成功',
								icon: 'success',
								duration: 2000,
								success: () => {
									setTimeout(() => {
										uni.navigateTo({
											url: '/pages/my-orders/my-orders'
										})
									}, 2000)
								}
							})
							// 更新订单支付状态
							this.updateOrderPaymentStatus(orderId, 1);
						}, err => {
							console.error('APP支付失败:', err)
							uni.showToast({
								title: '支付失败',
								icon: 'none'
							})
							this.isSubmitting = false
						})
					} else {
						uni.showModal({
							title: '支付提示',
							content: '当前环境不支持微信支付',
							showCancel: false,
							success: () => {
								this.isSubmitting = false
							}
						})
					}
				}, err => {
					console.error('获取支付通道失败:', err)
					uni.showToast({
						title: '支付初始化失败',
						icon: 'none'
					})
					this.isSubmitting = false
				})
			},
			// 选择附赠项目
			selectGiftService(gift) {
				// 如果次数小于等于0，直接返回
				if (gift.times <= 0) {
					return;
				}

				if (this.selectedGiftId === gift.id) {
					this.selectedGiftId = null;
					this.selectedGift = null;
				} else {
					this.selectedGiftId = gift.id;
					this.selectedGift = gift;
				}
			},
			// 拨打电话
			makePhoneCall() {
				if (!this.storeInfo.phone) {
					uni.showToast({
						title: '暂无联系电话',
						icon: 'none'
					});
					return;
				}

				uni.makePhoneCall({
					phoneNumber: this.storeInfo.phone,
					fail(err) {
						console.error('拨打电话失败:', err);
						uni.showToast({
							title: '拨打电话失败',
							icon: 'none'
						});
					}
				});
			},

			// 显示确认弹窗
			showConfirmDialog() {
				// 检查是否是技师账号
				if (this.isTechnician) {
					uni.showModal({
						title: '提示',
						content: '您当前登录的账号为技师账号，不可预约',
						showCancel: false,
						confirmText: '知道了'
					})
					return
				}

				// 检查所有必要信息是否已选择
				if (!this.techInfo.id) {
					uni.showToast({
						title: '请选择技师',
						icon: 'none'
					})
					return
				}

				if (!this.serviceInfo.id) {
					uni.showToast({
						title: '请选择服务项目',
						icon: 'none'
					})
					return
				}

				if (!this.selectedDate) {
					uni.showToast({
						title: '请选择预约日期',
						icon: 'none'
					})
					return
				}

				if (!this.selectedTime) {
					uni.showToast({
						title: '请选择预约时间',
						icon: 'none'
					})
					return
				}

				this.showMiniConfirm = true
			},

			// 取消确认
			cancelConfirm() {
				this.showMiniConfirm = false
			},

			// 检查是否还有未选择的项
			checkUnselectedItems() {
				const hasUnselected = !this.selectedStoreIndex ||
					!this.selectedServiceId ||
					!this.selectedDate ||
					!this.selectedTime

				this.showUnselectedTips = hasUnselected

				// 如果所有项都已选择，确保提示完全隐藏
				if (!hasUnselected) {
					this.$nextTick(() => {
						this.showUnselectedTips = false
					})
				}
			},

			// 滚动到门店
			scrollToStore() {
				uni.pageScrollTo({
					selector: '.map-container',
					duration: 300
				})
			},

			// 滚动到技师
			scrollToTechnician() {
				uni.pageScrollTo({
					selector: '.selected-tech',
					duration: 300
				})
			},

			// 滚动到服务项目
			scrollToService() {
				uni.pageScrollTo({
					selector: '.service-selection',
					duration: 300
				})
			},

			// 滚动到时间选择
			scrollToTime() {
				uni.pageScrollTo({
					selector: '.booking-time',
					duration: 300
				})
			},

			// 加载附加项目列表
			loadAdditionalServices() {
				uni.request({
					url: `${uni.$config.baseUrl}/project/project/listAll`,
					method: 'GET',
					data: {
						status: 1
					},
					success: (res) => {
						if (res.statusCode === 200 && res.data && res.data.code === 200) {
							// 筛选出艾灸、刮痧、拔罐三个项目
							const targetServices = ['艾灸', '刮痧', '拔罐']
							this.additionalServiceList = res.data.rows.filter(project =>
								targetServices.includes(project.projectName)
							)

							// 创建项目映射
							this.additionalServiceList.forEach(service => {
								this.additionalServicesMap[service.id] = service
							})
						}
					}
				})
			},

			// 切换附加项目选择状态
			toggleAdditionalService(service) {
				const index = this.selectedAdditionalServices.indexOf(service.id)
				if (index === -1) {
					this.selectedAdditionalServices.push(service.id)
				} else {
					this.selectedAdditionalServices.splice(index, 1)
				}
				this.calculateTotalPrice() // 重新计算总价
			},
		}
	}
</script>

<style lang="scss">
	.booking-fixed {
		min-height: 100vh;
		background: #F8F8F8;
		padding: 20rpx;
		padding-bottom: calc(120rpx + env(safe-area-inset-bottom));

		.map-container {
			width: 100%;
			height: 400rpx;

			.store-map {
				width: 100%;
				height: 100%;
			}
		}

		.store-info {
			background: #FFFFFF;
			border-radius: 16rpx;
			padding: 30rpx;
			margin: 20rpx;

			.store-card {
				.name {
					font-size: 32rpx;
					color: #333;
					font-weight: 600;
					margin-bottom: 12rpx;
					display: block;
				}

				.address {
					font-size: 26rpx;
					color: #666;
					margin-bottom: 12rpx;
					display: block;
				}

				.contact-info {
					display: flex;
					align-items: center;
					justify-content: space-between;

					.phone {
						font-size: 26rpx;
						color: #2B87FF;
						text-decoration: underline;
					}

					.distance {
						font-size: 24rpx;
						color: #999;
					}
				}
			}
		}

		.section-title {
			font-size: 32rpx;
			font-weight: 500;
			color: #333;
			padding: 0 10rpx 20rpx;
			display: flex;
			justify-content: space-between;
			align-items: center;

			.scroll-tip {
				font-size: 32rpx;
				color: #2B87FF;
				opacity: 0.8;
			}
		}

		.selected-tech,
		.service-selection,
		.booking-time,
		.remarks {
			background: #FFFFFF;
			border-radius: 16rpx;
			padding: 30rpx;
			margin-bottom: 7%;
		}

		.tech-card {
			display: flex;
			align-items: center;

			.avatar {
				width: 120rpx;
				height: 120rpx;
				border-radius: 60rpx;
				margin-right: 24rpx;
			}

			.info {
				flex: 1;

				.name-row {
					margin-bottom: 12rpx;

					.name {
						font-size: 32rpx;
						color: #333;
						font-weight: 600;
						margin-right: 16rpx;
					}

					.title {
						font-size: 26rpx;
						color: #666;
					}
				}

				.rating {
					.score {
						font-size: 28rpx;
						color: #FF6B6B;
						margin-right: 16rpx;
					}

					.orders {
						font-size: 24rpx;
						color: #999;
					}
				}
			}
		}

		.service-selection {
			background: #FFFFFF;
			border-radius: 16rpx;
			padding: 30rpx;
			margin-bottom: 20rpx;

			.service-list {
				height: 600rpx;
				overflow: hidden;

				.service-item {
					display: flex;
					align-items: flex-start;
					background: #F8F8F8;
					border-radius: 12rpx;
					padding: 20rpx;
					position: relative;
					border: 2rpx solid transparent;
					margin-bottom: 20rpx;

					&:last-child {
						margin-bottom: 0;
					}

					&.active {
						background: rgba(43, 135, 255, 0.05);
						border-color: #2B87FF;

						.name {
							color: #2B87FF;
						}

						.price {

							.symbol,
							.number {
								color: #2B87FF;
							}
						}
					}

					.service-image {
						width: 160rpx;
						height: 160rpx;
						border-radius: 8rpx;
						margin-right: 20rpx;
						background-color: #EEEEEE;
						flex-shrink: 0;
					}

					.service-content {
						flex: 1;
						display: flex;
						flex-direction: column;

						.name {
							font-size: 28rpx;
							color: #333;
							font-weight: 500;
							margin-bottom: 8rpx;
						}

						.desc {
							font-size: 24rpx;
							color: #666;
							margin-bottom: 16rpx;
							display: -webkit-box;
							-webkit-box-orient: vertical;
							-webkit-line-clamp: 2;
							overflow: hidden;
						}

						.info {
							display: flex;
							justify-content: space-between;
							align-items: center;
							margin-top: auto;

							.duration {
								display: flex;
								align-items: center;

								.duration-icon {
									width: 24rpx;
									height: 24rpx;
									margin-right: 6rpx;
								}

								text {
									font-size: 24rpx;
									color: #666;
								}
							}

							.price {
								display: flex;
								align-items: baseline;

								.symbol {
									font-size: 24rpx;
									color: #FF6B6B;
								}

								.number {
									font-size: 32rpx;
									color: #FF6B6B;
									font-weight: 500;
								}
							}
						}
					}
				}
			}
		}

		.time-slots {
			display: flex;
			flex-wrap: wrap;
			margin-top: 20rpx;
			max-height: 360rpx;
			overflow-y: auto;

			.time-slot {
				width: calc(30%);
				height: auto;
				min-height: 80rpx;
				margin: 8rpx;
				background: #F8F8F8;
				border-radius: 8rpx;
				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;
				padding: 12rpx 8rpx;

				.time-text {
					font-size: 28rpx;
					color: #333;
					margin-bottom: 4rpx;
				}

				.duration-text {
					font-size: 22rpx;
					color: #666;
					text-align: center;
					white-space: nowrap;
				}

				&.active {
					background: #2B87FF;

					.time-text {
						color: #FFFFFF;
					}

					.duration-text {
						color: rgba(255, 255, 255, 0.9);
					}
				}

				&.disabled {
					background: #EEEEEE;
					color: #999999;
					cursor: not-allowed;

					.time-text,
					.duration-text {
						color: #999999;
					}
				}
			}

			&::-webkit-scrollbar {
				width: 4rpx;
			}

			&::-webkit-scrollbar-thumb {
				background-color: #ddd;
				border-radius: 4rpx;
			}
		}

		.remark-input {
			width: 100%;
			height: 200rpx;
			background: #F8F8F8;
			border-radius: 12rpx;
			padding: 20rpx;
			font-size: 28rpx;
			color: #333;
		}

		.submit-section {
			position: fixed;
			bottom: 0;
			left: 0;
			right: 0;
			height: 7%;
			background: #FFFFFF;
			display: flex;
			align-items: center;
			justify-content: space-between;
			padding: 0 40rpx;
			padding-bottom: env(safe-area-inset-bottom);
			box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);

			.price-info {
				display: flex;
				align-items: baseline;

				.label {
					font-size: 28rpx;
					color: #666;
					margin-right: 12rpx;
				}

				.price {
					font-size: 40rpx;
					color: #FF6B6B;
					font-weight: 600;
				}
			}

			.submit-btn {
				width: 240rpx;
				height: 80rpx;
				background: #2B87FF;
				border-radius: 40rpx;
				display: flex;
				align-items: center;
				justify-content: center;
				box-shadow: 0 4rpx 12rpx rgba(43, 135, 255, 0.3);
				transition: all 0.3s ease;

				&:active {
					transform: scale(0.98);
					box-shadow: 0 2rpx 6rpx rgba(43, 135, 255, 0.2);
				}

				&.disabled {
					background: #CCCCCC !important;
					box-shadow: none !important;
					cursor: not-allowed;

					&:active {
						transform: none;
					}
				}

				text {
					font-size: 32rpx;
					color: #FFFFFF;
					font-weight: 500;
				}
			}
		}

		.mini-confirm-dialog {
			position: fixed;
			top: 0;
			left: 0;
			right: 0;
			bottom: 0;
			z-index: 999;
			display: flex;
			align-items: center;
			justify-content: center;

			.dialog-mask {
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				bottom: 0;
				background: rgba(0, 0, 0, 0.6);
			}

			.dialog-content {
				position: relative;
				width: 600rpx;
				background: #FFFFFF;
				border-radius: 20rpx;
				padding: 40rpx;
				z-index: 1000;

				.dialog-title {
					font-size: 32rpx;
					color: #333;
					font-weight: 600;
					text-align: center;
					margin-bottom: 20rpx;
				}

				.dialog-text {
					font-size: 28rpx;
					color: #666;
					text-align: center;
					margin-bottom: 20rpx;
				}

				.dialog-price {
					font-size: 40rpx;
					color: #FF6B6B;
					font-weight: 600;
					text-align: center;
					margin-bottom: 40rpx;
				}

				.dialog-buttons {
					display: flex;
					justify-content: space-between;

					button {
						width: 240rpx;
						height: 80rpx;
						border-radius: 40rpx;
						font-size: 28rpx;
						display: flex;
						align-items: center;
						justify-content: center;

						&.cancel-btn {
							background: #F5F5F5;
							color: #666;
						}

						&.confirm-btn {
							background: #2B87FF;
							color: #FFFFFF;
						}
					}
				}
			}
		}

		.date-list {
			display: flex;
			justify-content: space-between;
			padding: 20rpx 0;

			.date-item {
				flex: 1;
				text-align: center;
				padding: 20rpx 0;
				border-radius: 12rpx;
				background: #F8F8F8;
				margin: 0 10rpx;
				transition: all 0.3s;
				min-width: 160rpx;

				&:first-child {
					margin-left: 0;
				}

				&:last-child {
					margin-right: 0;
				}

				&.active {
					background: rgba(43, 135, 255, 0.1);

					.day,
					.date {
						color: #2B87FF;
					}
				}

				.day {
					font-size: 28rpx;
					color: #333;
					margin-bottom: 8rpx;
					display: block;
				}

				.date {
					font-size: 24rpx;
					color: #666;
					display: block;
				}
			}
		}

		.coupon-section {
			background: #FFFFFF;
			padding: 40rpx;
			margin-top: 24rpx;
			margin-bottom: 24rpx;

			.coupon-list {
				.coupon-item {
					display: flex;
					justify-content: space-between;
					align-items: center;
					padding: 30rpx;
					background: #F8F8F8;
					border-radius: 12rpx;
					margin-bottom: 20rpx;
					border: 2rpx solid transparent;
					transition: all 0.3s ease;

					&:last-child {
						margin-bottom: 0;
					}

					&.active {
						background: rgba(43, 135, 255, 0.05);
						border-color: #2B87FF;
					}

					.coupon-info {
						flex: 1;

						.coupon-name {
							font-size: 28rpx;
							color: #333;
							font-weight: 500;
							margin-bottom: 8rpx;
						}

						.coupon-desc {
							font-size: 24rpx;
							color: #666;
							margin-bottom: 8rpx;
						}

						.coupon-validity {
							font-size: 22rpx;
							color: #999;
						}
					}

					.coupon-amount {
						text-align: right;

						.amount {
							font-size: 36rpx;
							color: #FF6B35;
							font-weight: bold;
							display: block;
							margin-bottom: 8rpx;
						}

						.condition {
							font-size: 22rpx;
							color: #999;
						}
					}
				}

				.no-coupon {
					text-align: center;
					padding: 40rpx;
					color: #999;
					font-size: 28rpx;
				}
			}
		}

		.member-card-section {
			background: #FFFFFF;
			padding: 40rpx;
			margin-top: 24rpx;
			margin-bottom: 24rpx;

			.member-card-list {
				.member-card-item {
					display: flex;
					justify-content: space-between;
					align-items: center;
					padding: 30rpx;
					background: #F8F8F8;
					border-radius: 12rpx;
					margin-bottom: 20rpx;
					border: 2rpx solid transparent;
					transition: all 0.3s ease;

					&:last-child {
						margin-bottom: 0;
					}

					&.active {
						background: rgba(43, 135, 255, 0.05);
						border-color: #2B87FF;
					}

					.card-info {
						flex: 1;

						.card-name {
							font-size: 28rpx;
							color: #333;
							font-weight: 500;
							margin-bottom: 8rpx;
						}

						.card-desc {
							font-size: 24rpx;
							color: #666;
							margin-bottom: 8rpx;
						}

						.card-validity {
							font-size: 22rpx;
							color: #999;
						}
					}

					.card-action {
						.action-text {
							font-size: 26rpx;
							color: #2B87FF;
							background: rgba(43, 135, 255, 0.1);
							padding: 8rpx 24rpx;
							border-radius: 24rpx;
						}
					}
				}

				.no-card {
					text-align: center;
					padding: 40rpx;
					color: #999;
					font-size: 28rpx;
				}
			}
		}

		.gift-service-list {
			background: #FFFFFF;
			padding: 40rpx;
			margin-top: 24rpx;
			margin-bottom: 24rpx;

			.gift-list {
				.gift-item {
					background: #F8F8F8;
					border-radius: 12rpx;
					padding: 30rpx;
					margin-bottom: 20rpx;
					position: relative;
					border: 2rpx solid transparent;
					transition: all 0.3s ease;

					&:last-child {
						margin-bottom: 0;
					}

					&.active {
						background: rgba(43, 135, 255, 0.05);
						border-color: #2B87FF;

						.name {
							color: #2B87FF;
						}

						.action-text {
							color: #2B87FF;
						}
					}

					&.disabled {
						opacity: 0.5;
						pointer-events: none;
						background: #F5F5F5;

						.name {
							color: #999;
						}

						.times {
							color: #999;
						}

						.validity {
							color: #999;
						}

						.action-text {
							background: #EEEEEE;
							color: #999;
						}
					}

					.gift-info {
						display: flex;
						justify-content: space-between;
						align-items: center;
						margin-bottom: 12rpx;

						.name {
							font-size: 28rpx;
							color: #333;
							font-weight: 500;
						}

						.times {
							font-size: 24rpx;
							color: #FF6B6B;
							font-weight: 500;

							&.zero {
								color: #999;
							}
						}
					}

					.validity {
						font-size: 24rpx;
						color: #999;
						margin-bottom: 16rpx;
					}

					.action {
						text-align: right;

						.action-text {
							display: inline-block;
							font-size: 26rpx;
							color: #666;
							background: #EEEEEE;
							padding: 8rpx 24rpx;
							border-radius: 24rpx;
						}
					}
				}
			}
		}

		.unselected-tips {
			position: fixed;
			right: 30rpx;
			top: 120rpx;
			background: rgba(0, 0, 0, 0.7);
			padding: 20rpx;
			border-radius: 12rpx;
			z-index: 100;

			.tips-item {
				display: flex;
				align-items: center;
				padding: 12rpx 20rpx;
				font-size: 26rpx;
				color: #FFFFFF;
				white-space: nowrap;

				.icon {
					color: #FF6B35;
					margin-right: 12rpx;
					font-size: 24rpx;
				}

				.jump-text {
					margin-left: 20rpx;
					font-size: 24rpx;
					color: #2B87FF;
				}

				&:active {
					opacity: 0.8;
				}
			}
		}

		.additional-services {
			margin-bottom: 30rpx;

			.service-options {
				display: flex;
				flex-wrap: wrap;
				gap: 20rpx;
				margin-top: 20rpx;

				.service-option {
					flex: 1;
					min-width: 200rpx;
					padding: 20rpx;
					background: #F8F8F8;
					border-radius: 12rpx;
					display: flex;
					flex-direction: column;
					align-items: center;
					border: 2rpx solid transparent;
					transition: all 0.3s ease;

					.service-name {
						font-size: 28rpx;
						color: #333;
						margin-bottom: 8rpx;
					}

					.service-price {
						font-size: 24rpx;
						color: #666;
					}

					&.active {
						background: rgba(43, 135, 255, 0.05);
						border-color: #2B87FF;

						.service-name {
							color: #2B87FF;
						}

						.service-price {
							color: #2B87FF;
						}
					}

					&:active {
						transform: scale(0.98);
						opacity: 0.9;
					}
				}
			}
		}
	}
</style>